package statemachine;

import com.alibaba.cola.statemachine.Action;
import com.alibaba.cola.statemachine.Condition;
import com.alibaba.cola.statemachine.StateMachine;
import com.alibaba.cola.statemachine.builder.StateMachineBuilder;
import lombok.Data;

/**
 * @Author zhangtao
 * @create 2023/8/9 15:47
 */

public class ApprovalStatemachine {
    // 审核状态：1：已撤回；2：待审核，3：已驳回，4：已通过
    enum ApprovalStatus {
        REVOKE,
        TO_APPROVE,
        REJECT,
        PASS;
    }

    // 审核事件
    enum ApprovalEvent {
        REJECT,
        PASS,
        REVOKE;
    }

    @Data
    static class Approval {
        long approvalId;
        boolean sucess;
    }

    static String MACHINE_ID = "approvalStateMachine";

    public void testExternalTransitionsNormal() {
        StateMachineBuilder<ApprovalStatus, ApprovalEvent, Approval> builder = new CustomStateMachineBuilderImpl<>();

        builder.externalTransitions()
                .fromAmong(ApprovalStatus.TO_APPROVE)
                .to(ApprovalStatus.PASS)
                .on(ApprovalEvent.PASS)
                .when(checkCondition())
                .perform(doAction());

        builder.externalTransitions()
                .fromAmong(ApprovalStatus.TO_APPROVE)
                .to(ApprovalStatus.REJECT)
                .on(ApprovalEvent.REJECT)
                .when(checkCondition())
                .perform(doAction());

        builder.externalTransitions()
                .fromAmong(ApprovalStatus.TO_APPROVE)
                .to(ApprovalStatus.REVOKE)
                .on(ApprovalEvent.REVOKE)
                .when(checkCondition())
                .perform(doAction());

        StateMachine<ApprovalStatus, ApprovalEvent, Approval> stateMachine = builder.build(MACHINE_ID + "2");

        stateMachine.fireEvent(ApprovalStatus.TO_APPROVE, ApprovalEvent.REJECT, new Approval(), (from, to, event, ctx) -> {
            ctx.sucess = true;

        });

        ApprovalStatus target = stateMachine.fireEvent(ApprovalStatus.TO_APPROVE, ApprovalEvent.PASS, new Approval());
        System.out.println(target);
    }

    private Condition<Approval> checkCondition() {
        return approval -> {
            //审批单状态更新和审批记录新增操作
            System.out.println("Check condition : " + approval);
            return true;
        };
    }

    private Action<ApprovalStatus, ApprovalEvent, Approval> doAction() {
        return (from, to, event, ctx) -> {
            ctx.sucess = true;
        };
    }

    public static void main(String[] args) {
        ApprovalStatemachine statemachine = new ApprovalStatemachine();
        statemachine.testExternalTransitionsNormal();
    }


}
